/* 
 * File:   HttpPool.cpp
 * Author: tzl
 * 
 * Created on July 4, 2011, 9:19 AM
 */
#include "stdafx.h"
#include "HttpPool.h"
#include "Global.h"

////////////////////////////////////////////////////////////////////////////////
HttpConn::~HttpConn()
{
	if (_feedback)
		_feedback->free();

	if (_req)
		delete _req;
}

////////////////////////////////////////////////////////////////////////////////

HttpPool::HttpPool()
{

}

HttpPool::~HttpPool()
{
	
}

bool HttpPool::start()
{
	if (!_ioPool.create(1, 4096, 1024, 4096)) {
		// log error
		assert(false);
		return false;
	}

	_ioPool.registerEventHandler(this);
	return _ioPool.start();
}

bool HttpPool::request(const sockaddr* addr, size_t addrlen, HttpReqBuilder* req,
	HttpFeedback* feedback)
{
	HttpConn* conn = new HttpConn;
	conn->_feedback = feedback;
	conn->_req = req;
	if (_ioPool.connect(addr, addrlen, conn) == NULL) {

		delete conn;
		return false;
	}

	return true;
}

bool HttpPool::onInit(FileObjPtr& file)
{
	return true;
}

void HttpPool::onUninit(FileObject* file)
{
	HttpConn* conn = (HttpConn* )file->getData();
	delete conn;
}

void HttpPool::onConnect(FileObjPtr& file, int errcod)
{
	if (errcod != 0)
		return;

	HttpConn* conn = (HttpConn* )file->getData();
	std::string str = conn->_req->buildPacket();
	file->write(str.c_str(), str.size());
}

void HttpPool::onDataIn(FileObjPtr& file, NetBuff* buf)
{
	HttpConn* conn = (HttpConn* )file->getData();
	assert(conn);
	
	HttpResponseParser& parser = conn->_parser;
	char* httpResp = NULL;
	size_t len;
	size_t dataPos;

	if (parser.parse(buf->data, buf->size)) {
		
		len = parser.getResponseSize();
		httpResp = (char* )malloc(len + 1);
		if (parser.getResponse(httpResp, len + 1, &dataPos) <= 0) {
			// log error
			free(httpResp);
			return;
		}

		httpResp[len] = 0;
		
	} else {

		return;
	}

	assert(httpResp);
	assert(conn->_feedback);
	if (dataPos < len)
		conn->_feedback->onResponse(httpResp + dataPos, len - dataPos);
	else {
		svrLog->log(LogDebug, "%s(): HTTP ERROR: %s", __FUNCTION__, httpResp);
	}
	
	free(httpResp);	
	file->close(); // FIXME: 
}
